package Dao;

import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;





import Negocio.ItemListaPreciosCPR;
import Negocio.ListaPrecios;
import Negocio.ListaPreciosCPR;
import Negocio.Proveedor;
import Negocio.Rodamiento;
import Persistencia.HibernateUtil;

public class ProveedorDao {
	
	private static ProveedorDao instancia = null;
	private static SessionFactory sf = null;
	
	public static ProveedorDao getInstancia() {
		if(instancia == null){
			sf = HibernateUtil.getSessionFactory();
			instancia = new ProveedorDao();
		} 
		return instancia;
	}
	
	public void agregarProveedor(Proveedor pro)  {		
		
		Session session = null;
		try {
			session = sf.openSession();			
			session.beginTransaction();
			session.save(pro);			
			session.getTransaction().commit();
			session.flush();
			session.close();		
		} catch (Exception e) {
			if(session != null){
				session.getTransaction().rollback();	
				session.flush();
				session.close();
//				throw new RemoteException();
			}			
		}		
	}
	
	public Proveedor buscarProveedorXCodigo(int codigo) {
		Session session = sf.openSession();
		session.beginTransaction();
		Proveedor proveedor = (Proveedor)session.get(Proveedor.class, codigo);
		if(proveedor!= null) proveedor.getListas().size(); //FIXME: parche porque tira lazzy load exception.
		session.flush();
		session.getTransaction().commit();
		session.close();
		return proveedor;
	}	
	
	public void modificarProveedor(Proveedor prov) throws RemoteException {
		Session session = null;
		try {
			session = sf.openSession();
			session.beginTransaction();		
			session.flush();
			session.update(prov);
			session.flush();
			session.getTransaction().commit();
			session.close();
		} catch (Exception e) {	
			if(session != null){
				session.getTransaction().rollback();
				session.flush();
				session.close();
				throw new RemoteException();
			}	
			throw new RemoteException();
		}		
	}

	public void borrarProveedor(int codigo) {
		Session session = sf.openSession();
		session.beginTransaction();
		Proveedor proveedor = (Proveedor)session.get(Proveedor.class, codigo);
		session.delete(proveedor);
		session.flush();
		session.getTransaction().commit();
		session.close();		
	}

	public ArrayList<Proveedor> obtenerProveedores() {
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from Proveedor");		
		ArrayList<Proveedor> proveedores = new  ArrayList<Proveedor>(query.list());
		Iterator<Proveedor> it = proveedores.iterator();
		while(it.hasNext())
		{
			it.next().getListas().size();
		}
		session.flush();
		session.getTransaction().commit();
		session.close();
		return new ArrayList<Proveedor>(proveedores);
	}

	public Proveedor buscarProveedorXNombre(String proveedor) {
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from Proveedor where nombre = ?");
		query.setString(0, proveedor);
		Proveedor prov = (Proveedor) query.uniqueResult();
		if(prov!= null) prov.getListas().size(); //FIXME: parche porque tira lazzy load exception.
//		PaisOrigen paisOrigen = (PaisOrigen)session.get(PaisOrigen.class, origen);
		session.flush();
		session.getTransaction().commit();
		session.close();
		return prov;		
	}

	public Proveedor buscarProveedorXCuit(String proveedor) {
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from Proveedor where cuit = ?");
		query.setString(0, proveedor);
		Proveedor prov = (Proveedor) query.uniqueResult();
		if(prov!= null) prov.getListas().size(); //FIXME: parche porque tira lazzy load exception.
//		PaisOrigen paisOrigen = (PaisOrigen)session.get(PaisOrigen.class, origen);
		session.flush();
		session.getTransaction().commit();
		session.close();
		return prov;		
	}
	public Object[] obtenerPreciosMinimoRodamiento(String codigo,String marca,String origen) {
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("SELECT lp.tipo,item.precioCompra,item.marca,item.origen,item.tipo,lp.proveedor " +
				" FROM ItemListaPrecios item INNER JOIN item.lista lp" +
				" WHERE item.rodamiento.codigo = ? and lp.vigente = ? ORDER BY precioCompra ASC");
		query.setString(0, codigo);
		query.setBoolean(1, true);
		//TODO: VER COMO ES!!!
		Object o[]=  (Object[]) query.list().get(0);
		session.flush();
		session.getTransaction().commit();
		session.close();
		return o;		
		
	}
	
	public ArrayList<Object[]> obtenerPreciosRodamientos(String codigo,String marca, String pais) {
		Session session = sf.openSession();
		session.beginTransaction();
		String where=" WHERE item.rodamiento.codigo = ? and lp.vigente = ? ";
		if(marca != null && !marca.equals("") )
			where = where + " and item.rodamiento.marca = :marca ";
		if(pais != null && !pais.equals("") )
			where = where + " and item.rodamiento.origen = :pais ";
		Query query = session.createQuery("SELECT lp.tipo,item.precioCompra,item.marca,item.origen,item.tipo,lp.proveedor,item.rodamiento " +
				" FROM ItemListaPrecios item INNER JOIN item.lista lp" + where +
				"ORDER BY precioCompra ASC");
		query.setString(0, codigo);
		query.setBoolean(1, true);
		if(marca != null && !marca.equals("") )
			query.setParameter("marca",marca); 
		if(pais != null && !pais.equals("") )
			query.setParameter("pais",pais);

		ArrayList<Object[]> o=  new ArrayList<Object[]>(query.list());
		//System.out.println("ProveedorDAO::obtenerPreciosRodamientos -> cantidad objetos:"+ Integer.toString(o.size()));
		session.flush();
		session.getTransaction().commit();
		session.close();
		return o;		
	}	
	
	public ListaPreciosCPR obtenerListaPreciosCPR()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from ListaPreciosCPR ");
		ListaPreciosCPR l = (ListaPreciosCPR) query.uniqueResult();
		if(l!=null)l.getItems().size();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return l;
	}
	
	public void guardarListaPreciosCPR(ListaPreciosCPR l)
	{
		Session session = sf.openSession();
		session.beginTransaction();
		session.save(l);
		Iterator<ItemListaPreciosCPR> it = l.getItemsToSave().iterator();
		while(it.hasNext())
		{
			session.save(it.next());
		}
		session.flush();
		session.getTransaction().commit();
		session.close();
	}

	public void borrarListaPrecioCRP() {
		ListaPreciosCPR l=obtenerListaPreciosCPR();
		if(l==null)return; // no hay lista de precios anterior
		Session session = sf.openSession();
		session.beginTransaction();		
		session.delete(l);
		session.flush();
		session.getTransaction().commit();
		session.close();				
	}

	public void guardarListaPrecios(ListaPrecios l) {
		// TODO Auto-generated method stub
		Session session = null;
		try {
			session = sf.openSession();			
			session.beginTransaction();
			session.save(l);			
			session.getTransaction().commit();
			session.flush();
			session.close();		
		} catch (Exception e) {
			if(session != null){
				session.getTransaction().rollback();	
				session.flush();
				session.close();
//				throw new RemoteException();
			}			
		}		
	}


	public ArrayList<ItemListaPreciosCPR> getItemsListaPrecioCPR() {
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from ItemListaPreciosCPR ");
		ArrayList<ItemListaPreciosCPR> l = new ArrayList<ItemListaPreciosCPR> (query.list());
		session.flush();
		session.getTransaction().commit();
		session.close();
		return l;
	}


}


